package com.xyzwps.server.paimon.spring

import com.xyzwps.server.paimon.error.Errors
import com.xyzwps.server.paimon.common.ReqCtx
import com.xyzwps.server.paimon.model.repository.v
import org.springframework.core.MethodParameter
import org.springframework.web.bind.annotation.ValueConstants
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.web.context.request.RequestAttributes
import org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver

/**
 * @see org.springframework.web.servlet.mvc.method.annotation.RequestAttributeMethodArgumentResolver
 */
class AuthUserResolverForMvc : AbstractNamedValueMethodArgumentResolver() {

    override fun supportsParameter(parameter: MethodParameter) =
        parameter.hasParameterAnnotation(AuthUser::class.java)

    override fun createNamedValueInfo(parameter: MethodParameter): NamedValueInfo {
        val ann = getAnnotation(parameter)
        return NamedValueInfo(ReqCtx.USER, ann.required, ValueConstants.DEFAULT_NONE)
    }

    override fun resolveName(name: String, parameter: MethodParameter, request: NativeWebRequest): Any? {
        val ann = getAnnotation(parameter)
        val value = request.getAttribute(name, RequestAttributes.SCOPE_REQUEST)
        if (ann.required && value == null) {
            throw Errors.UNAUTHENTICATED.toEx()
        }
        return value
    }

    private fun getAnnotation(parameter: MethodParameter): AuthUser =
        parameter.getParameterAnnotation(AuthUser::class.java)
            ?: throw IllegalStateException("No AuthUser annotation")
}